package snafu.framework.actions;

import java.util.Arrays;
import java.util.List;

import snafu.framework.agents.AgentState;
import snafu.framework.objects.WorldObject;
import snafu.framework.view.Access;
import snafu.framework.view.View;
import snafu.framework.worlds.WorldMap;

public abstract class IntentionView<A extends AbstractAction> implements Intention<A>, View {

	/** The access type. */
	protected Access access;
	/** The original intention. */
	protected IntentionItself<A> intention;
	
	/**
	 * Creates a new intention view with the given access type and the intention as the original
	 * value.
	 * 
	 * @param access
	 *            the access type
	 * @param intention
	 *            the original intention
	 */
	public IntentionView(Access access, IntentionItself<A> intention) {
		this.access = access;
		this.intention = intention;
	}
	
	/**
	 * Returns the same value as the original intention would.
	 */
	@Override
	public boolean isApplicable(WorldMap perception, AgentState agent, List<WorldObject> targets) {
		return intention.isApplicable(perception, agent, targets);
	}
	
	/**
	 * Returns the same value as the original intention would.
	 */
	@Override
	public boolean isApplicable(WorldMap perception, AgentState agent, WorldObject... targets) {
		return intention.isApplicable(perception, agent, targets);
	}	
	
	@Override
	public boolean equals(Object o) {
		if (!(o instanceof Intention<?>))
			return false;
		
		Class<?>[] interfaces = this.getClass().getInterfaces();
		
		for (Class<?> clazz : interfaces) {
			if (clazz.isAssignableFrom(o.getClass()) && clazz.isAssignableFrom(this.getClass())
					&& Intention.class.isAssignableFrom(clazz))
				return true;
		}
		
		return false;
	}
	
	/**
	 * Creates the action through the original intention.
	 */
	@Override
	public A createAction(WorldObject... targets) {
		return intention.createAction(Arrays.asList(targets));
	}
}
